/**
 * Created by zg
 */
define(['jquery', 'angular', 'app.services', 'layer'], function ($, angular, services, layer) {
    'use strict';

  /*  services.loadJs = function(js){
        return function($rootScope, $q){
            var def = $q.defer(), deps=[];

            angular.isArray(js) ? (deps = js) : deps.push(js);
            require(deps,function(){
                $rootScope.$apply(function(){
                    def.resolve();
                });
            });
            return def.promise;
        };
    }*/
    /**
     * requirejs 加载模块
     */
    services.provider('RequireResolve', [function () {

        /**
         * requirejs 加载模块
         * @param parameters
         * @returns {*[]}
         */
        this.requirejs = function (parameters) {
            return [
                '$q', function ($q) {
                    var def = $q.defer();
                    require(parameters, function () {
                        def.resolve();
                    });
                    return def.promise;
                }
            ];
        };

        this.$get = $get;
        $get.$inject = ['$q', '$rootScope'];

        function $get($q, $rootScope) {
            return {
                /**
                 * requirejs 加载模块
                 * @param parameters
                 * @returns {Promise}
                 */
                requirejs: function (parameters) {
                    return $q(function (resolve, reject) {
                        require(parameters, function () {
                            resolve(arguments);
                        });
                    });
                }
            };
        }
        services.service('Base', [function () {
            /**
             * 拼接字符串
             * @returns {*}
             */
            this.stringFormat = function () {
                if (arguments.length == 0) return null;

                var str = arguments[0];
                for (var i = 1; i < arguments.length; i++) {
                    var re = new RegExp('\\{' + (i - 1) + '\\}', 'gm');
                    str = str.replace(re, arguments[i]);
                }
                return str;
            };
            var Config = {
                // 数据代理前缀，用于//domain.com/{dataPrefix}/{app(应用)}的dataPrefix，默认为 dapi，默认处理在Base.js中处理
                // 此项请不要添加任何'/'字符，非特殊情况此节点不会变更
                DATA_PREFIX: "api",

            };
            this.dataApiUri = {

                login :this.stringFormat("/{0}", Config.DATA_PREFIX),
                /**
                 * 用户服务地址
                 */
                student: this.stringFormat("/{0}", Config.DATA_PREFIX),

            };


        }]);
    }]);
    /*
     * 跳转服务
     *
     * */
    services.service("Jump", ["$window", "Base", function ($window, Base) {

        //跳转到
        this.to = function (target) {
            var ref = $window.location.href || "";
            ref = encodeURI(ref.replace('#', '@@'));

            //地址是否有参数
            var index = target.lastIndexOf('?');
            //已经有参数
            if (index > 0) {
                target = Base.stringFormat("{0}&ref={1}", target, ref)
            } else {
                target = Base.stringFormat("{0}?ref={1}", target, ref)
            }

            $window.location.href = target;
        };

        //获取跳转地址
        this.getBackAddress = function () {
            return Base.getURLParameter('ref');
        };

        this.getCurrentPath = function () {
            return $window.location.pathname;
        };

        this.toEn = function () {
            $window.location.href = Base.stringFormat("{0}{1}", Base.links.en, this.getCurrentPath());
        };

        this.toCn = function () {
            $window.location.href = Base.stringFormat("{0}{1}", Base.links.cn, this.getCurrentPath());
        };

        //返回到
        this.go = function (defaultTarget) {
            var backTo = decodeURI(this.getBackAddress()) || "";

            var hashIndex = backTo.lastIndexOf("#");
            if (hashIndex > -1) {
                backTo = backTo.substring(0, backTo.lastIndexOf('#'));
            }

            backTo = backTo.replace('@@', '#');

            if (backTo && backTo != "null" && backTo.length > 0) {
                $window.location.href = backTo;
            } else if (defaultTarget) {
                $window.location.href = defaultTarget;
            }
        };

    }]);
    /**
     * 消息类型（图标）
     */
    services.service("MessageType", [function () {
        /**
         * 一般信息
         */
        this.information = -1;
        /**
         * 警告（叹号）
         */
        this.warning = 0;
        /**
         * 成功（对号）
         */
        this.succeed=1;
        /**
         * 错误（叉号）
         */
        this.error = 2;
        /**
         *询问（问号）
         */
        this.ask = 3;
        /**
         * 禁止操作（小锁头）
         */
        this.disable = 4;
        /**
         * 不开心（娃娃脸悲伤）
         */
        this.sad = 5;
        /**
         * 开心（娃娃脸开心）
         */
        this.happy = 6;
        /**
         * 下载
         */
        this.download = 7
    }]);

    /**
     * 窗口类型
     */
    services.service("WindowType", [function () {
        /**
         * 消息框
         */
        this.alert = 0;
        /**
         * 询问框
         */
        this.confirm = 1;
        /**
         * 输入框
         */
        this.prompt = 2;
        /**
         * 加载框
         */
        this.loading = 3;
        /**
         * 提示框
         */
        this.title = 4;
        ///**
        // * iframe窗口
        // */
        //this.iframeWindow = 5;
        /**
         * 页面内容window
         */
        this.contentWindow = 6;
        /**
         * 警告框
         * @type {number}
         */
        this.warning = 7;
    }]);
    /**
     * 消息对话框服务 提供平台消息提示处理
     */
    services.service('MessageBox', ['$q', '$http', '$compile', '$rootScope', 'WindowType', 'RequireResolve', function ($q, $http, $compile, $rootScope, WindowType, RequireResolve) {

        var _MessageBox = null;

        /**
         * 显示消息框
         * @param handler
         * @param message
         * @param windowType
         * @param messageType
         */
        this.show = function (message, windowType, messageType, options) {

            options = options || {
                    /**
                     * 默认自动关闭弹出
                     */
                    defaultClose: true
                    /**
                     * 输入框默认值
                     */
                    , defalutValue: ""
                    /**
                     * 输入框的默认类型 0（文本）默认1（密码）2（多行文本）
                     */
                    , formType: 0
                    /**
                     * 模板URL
                     */
                    , templateUrl: null
                    /**
                     * 模板内容
                     */
                    , template: ""
                    /**
                     * 加载层是否有背景
                     */
                    ,isBackGround : true
                    /**
                     * 提示层关闭时间
                     */
                    ,time : 3000
                    /**
                     * 是否具有遮罩层
                     */
                    ,shade : false
                };

            options.messageType = messageType;
            //背景色
            if(options.shade){
                options.shade = [0.2, '#393D49'];
            }

            switch (windowType) {
                case WindowType.alert:
                    return _MessageBox.alert(message, messageType, options.defaultClose);
                    break;
                case WindowType.confirm:
                    return _MessageBox.confirm(message, messageType,options.btn);
                    break;
                case WindowType.prompt:
                    return _MessageBox.prompt(message, options.defalutValue, options.formType);
                    break;
                case WindowType.contentWindow:
                    return _MessageBox.contentPage(message, options);
                    break;
                case WindowType.loading:
                    return _MessageBox.loading(options);
                    break;
                case WindowType.title:
                    return _MessageBox.title(message,options);
                    break;
                case WindowType.warning:
                    return _MessageBox.warning(message,options);
                    break;
            }

        };
        /**
         * 弹出框
         */
        this.alert=function(message,icon){
            return _MessageBox.alert(message,icon?icon:5,true);
        }
        /**
         * 询问框
         */
        this.confirm=function(message,icon){
            return _MessageBox.confirm(message, icon);
        }
        /**
         * 消息提示框
         */
        this.msg=function(message,icon){
            return this.show(message,WindowType.title,icon?icon:2);
        }
        /**
         * MapKey是否存在
         * @param key
         * @returns {*}
         */
        this.isExists = function(key){
            return _MessageBox.mapKey[key];
        };

        /**
         * 弹出层关闭
         * @param key
         */
        this.close = function (key) {
            _MessageBox.close(key);
        };
        /**
         * 消息框
         * @constructor
         */
        var MessageBox = function () {
            this.init();
            this.mapKey = {};
        };

        MessageBox.prototype = {
            init: function () {
                //使用第三方皮肤 详情:http://layer.seaning.com/
                layer.config({
                    skin: 'layui-layer-molv',
                    extend: 'skin/moon/style.css'
                });
            },

            /**
             * 一般弹出框
             * @param message
             * @param messageType
             * @param yes
             */
            alert: function (message, messageType, defaultClose) {
                var index = 0;
                var close = function () {
                    layer.close(index);
                };
                if (defaultClose) {
                    layer.alert(message, {
                        icon: messageType,
                        skin: 'layui-layer-molv',
                        closeBtn : 0
                    });
                } else {
                    return $q(function (resolve, reject) {
                        index = layer.alert(message, {
                            icon: messageType,
                            skin: 'layer-ext-moon',
                            closeBtn : 0
                        }, function () {
                            resolve(close);
                        });
                    });
                }
            },
            /**
             * 询问框
             * @param message
             * @param yes
             * @param no
             */
            confirm: function (message, messageType,btn) {

                var index = 0;

                var close = function () {
                    layer.close(index);
                    return true;
                };

                return $q(function (resolve, reject) {
                    index = layer.confirm(message, {
                        icon: messageType?messageType:3,
                        skin: 'layui-layer-molv',
                        btn : btn,
                        closeBtn : 0
                    }, function () {
                        resolve({result : true,close : close});
                    }, function () {
                        resolve({result : false,close : close});
                    });
                });
            },

            /**
             * 输入框
             * @param title
             * @param defalutValue
             * @param formType
             * @returns {*}
             */
            prompt: function (title, defalutValue, formType) {
                var index = 0;

                var close = function () {
                    layer.close(index);
                    return true;
                };

                return $q(function (resolve, reject) {
                    index = layer.prompt({
                        formType: formType,
                        value: defalutValue,
                        title: title,
                        closeBtn : 0,
                        cancel: function () {
                            reject();
                        }
                    }, function (value, index, elem) {
                        resolve({value: value, index: index, elem: elem, close: close});
                    });
                });
            },

            /**
             * 内容层
             * @param options
             */
            contentPage: function (name, options) {

                var loadingKey = "loadingKey_"+new Date().getTime();

                //显示加载层
                this.loading({
                    key :loadingKey,
                    isBackGround : true
                });

                var _this = this;
                var index = 0;
                var require = 0;
                if (angular.isArray(options.require) && options.require.length > 0) {
                    require = RequireResolve.requirejs(options.require);
                }

                if (options.templateUrl) {
                    var request = $http({
                        method: 'GET',
                        url: options.templateUrl
                    });

                    //页面加载成功
                    request.success(function (response) {
                        $q.when(require).then(function () {
                            index = layer.open({
                                type: 1,
                                title: name,
                                skin: 'layui-layer-rim', //加上边框
                                area: [options.width, options.height], //宽高
                                content: response,
                                success: function (layero) {
                                    //关闭弹出层
                                    _this.close(loadingKey);

                                    var content = layero.find(".layui-layer-content")
                                    var link = $compile(content.html());
                                    content.html(link($rootScope));
                                }
                            });

                            //记录层标识
                            _this.mapKey[options.key] = index;
                        });

                    });
                } else {
                    $q.when(require).then(function () {
                        index = layer.open({
                            type: 1,
                            title: name,
                            skin: 'layui-layer-rim', //加上边框
                            area: [options.width, options.height], //宽高
                            content: options.template,
                            success: function (layero) {
                                //关闭弹出层
                                _this.close(loadingKey);
                                var content = layero.find(".layui-layer-content")
                                var link = $compile(content.html());
                                content.html(link($rootScope));
                            }
                        });
                        //记录层标识
                        _this.mapKey[options.key] = index;
                    });
                }
            },
            /**
             * 加载层
             * @param isBackGround
             */
            loading : function(options){
                var _this = this;
                var index = 0;
                if(options.isBackGround){
                    index = layer.load(0, {shade: false});
                }else{
                    index = layer.load(0, {shade: false});
                }

                //记录层标识
                _this.mapKey[options.key] = index;
            },
            /**
             * 提示层
             * @param name
             */
            title : function(name,options){
                var index = layer.msg(name, {
                    icon: options.messageType?options.messageType:0,
                    skin: 'layui-layer-molv',
                    time : options.time,
                    shade : options.shade
                },function(){
                    $rootScope.$broadcast("messageContentPageClosed", {key: options.key});
                });
                //记录层标识
                this.mapKey[options.key] = index;
            },
            /**
             * 警告框
             * @param name
             * @param options
             */
            warning : function(name,options){
                layer.msg(name, {
                    icon: options.messageType?options.messageType:0,
                    skin: 'layer-ext-moon',
                    time : options.time,
                    offset: 0,
                    shift: 6
                },function(){
                    $rootScope.$broadcast("messageContentPageClosed", {key: options.key});
                });
            },
            /**
             * 关闭弹出层
             */
            close: function (key) {
                var index = this.mapKey[key];
                if (index) {
                    layer.close(index);
                    $rootScope.$broadcast("messageContentPageClosed", {key: key});
                }
            }
        };

        _MessageBox = new MessageBox();
    }]);

    /**
     * 异常信息类
     */
    services.service("Exception", ['$q','$injector',function ($q,$injector) {

        //过期的URL
        var expireUrls = [];

        /**
         * 获错误取消息
         * @param type
         * @param message
         * @returns {{message: *, status: number, type: *}}
         */
        this.getMessage = function (type, message) {
            return {
                message: message,
                status: 0,
                type: type
            };
        };
        /**
         * 错误处理
         */
        this.catch = function (response) {
            var message = null;
            var status = response.status;
            switch (status) {
                case "401":
                    message = this.getMessage('401', '您没有获取资源的权限获取登录已失效,请重新登陆后重试。');
                    break;
                case "404":
                    message = this.getMessage('404', '没有找到相关资源。');
                    break;
                case "415":
                    message = this.getMessage('415', '请求资源方式不正确,请检查资源请求方式。');
                    break;
                case "500":
                    message = this.getMessage('500', '资源服务异常。');
                    break;
                default:
                    //如果登陆已过期
                    if(response.data && response.data.type == 'no-login'){
                        againUser(response);
                        if(response.isArray){
                            response.data = [];
                        }else{
                            response.data = {};
                        }

                        return $q.resolve(response)
                    }

                    return $q.reject(response.data);
            }

            return $q.reject(message);
        };

        /**
         * 重新登陆
         */
        var againUser = function(response){
            return $injector.invoke(['$http','$rootScope','MessageBox','WindowType',function($http,$rootScope,MessageBox,WindowType){
                var deferred = $q.defer();

                expireUrls.push(response.config);

                //if(!MessageBox.isExists('relogin')){

                    //重新登陆事件
                    $rootScope.$broadcast("relogin", {});

                    MessageBox.show("登陆过期,重新登陆",WindowType.contentWindow,null,{
                        //弹出层的名字 必须唯一
                        key : "relogin",
                        width : "420px",
                        height : "240px",
                        require : ['directives/common/login'],
                        template : "<relogin></relogin>"
                    });


                    $(document).on('reloginSuccess',function(event,args){
                        MessageBox.close('relogin');
                        //重新登陆成功事件
                        $rootScope.$broadcast("reloginSuccess", {});
                        window.location.reload();
                        return $http(response.config);
                    });
              // }

                return deferred;

            }]);
        };
    }]);
    /**
     * 服务数据解析
     */
    services.service("DataAnalysis", ['$q', 'Exception', function ($q, Exception) {

        /**
         * 成功数据转换
         */
        this.parse = function (response) {
            if (!response || !response.data) {
                return $q.reject(response);
            }
            if (response.data.status == 0 && !angular.isUndefined(response.data.message)) {
                return this.catch(response);
            } else if (response.data.status == 1 && !angular.isUndefined(response.data.message)) {
                if(response.data.data){
                    response.data = response.data;
                    if(angular.isString(response.data)){
                        response.data = {data : response.data};
                    }
                }else{
                    response.data = response.data;
                }

                return $q.resolve(response);
            }

            return $q.resolve(response);
        };

        /**
         * 错误数据拦截
         * @param response
         */
        this.catch = function (response) {
            return Exception.catch(response);
        };
    }]);

    /**
     * 资源拦截服务
     */
    services.service("ResourceInterceptor", ['$q','$templateCache', '$injector', 'DataAnalysis','Exception', function ($q,$templateCache, $injector, DataAnalysis,Exception) {



        //response 请求  拦截
        this.response = function (response) {
            return ResourceSuccessDataHandler(response);
        };

        //request  错误拦截
        this.requestError = function (request) {

            return $q.reject(request);
        };

        //response 错误拦截
        this.responseError = function (response) {
            return ResourceErrorDataHandler(response);
        };


        //资源成功数据处理
        function ResourceSuccessDataHandler(response) {
            if (!response) {
                return $q.resolve(response);
            }

            //模板数据直接返回
            if (response.config.url.indexOf('.html') > -1 || response.config.url.indexOf('.htm') > -1) {
                return $q.resolve(response);
            }
            //进行整理数据
            return DataAnalysis.parse(response);
        }

        //资源失败数据处理
        function ResourceErrorDataHandler(response) {
            if (!response || !response.config) {
                return $q.reject(response);
            }

            //模板数据直接返回
            if (response.config.url.indexOf('.html') > -1 || response.config.url.indexOf('.htm') > -1) {
                return $q.reject(response);
            }

            //进行整理数据
            return $q.reject(Exception.catch(response));
        }
    }]);

    //缓存管理
    window.cache = {User : {}};
    /**
     * 缓存控制器
     */
    services.service("CacheManager",['$cacheFactory',function($cacheFactory){

        //用户缓存接收器
        this.User =window.cache.User;
    }])
});